import { cloneDeep } from '@/utils'
import defaultOptions from './default-options'

const settoolbarConfig = function ({
  tableOptions,
  exportConfig,
  importConfig
}) {
  let { toolbarConfig = {} } = tableOptions

  const { tools = [] } = toolbarConfig

  toolbarConfig = {
    ...toolbarConfig,
    ...defaultOptions.toolbarConfig,

    tools: [...tools, ...defaultOptions.toolbarConfig.tools]
  }

  toolbarConfig.tools.find((d) => d.code === 'yExportCode').visible =
    !!exportConfig
  toolbarConfig.tools.find((d) => d.code === 'yImportCode').visible =
    !!importConfig

  return toolbarConfig
}

const setTypeSlots = function (column) {
  const whiteList = ['seq', 'checkbox', 'radio', 'expand', 'html']
  const mask = 'type'

  let slotName = ''
  let { type } = column

  if (type && !whiteList.includes(type)) {
    const name = type + '_' + mask + '_default'
    column.slots = {
      default: name
    }
    slotName = name
    column.type = ''
  }
  return {
    slotName
  }
}

const setCellRenderSlots = function (column) {
  const { cellRender } = column
  const mask = 'cell'

  let slotName = ''
  if (cellRender && cellRender.name) {
    const name = cellRender.name + '_' + mask + '_default'
    column.slots = {
      default: name
    }
    slotName = name
  }
  return {
    slotName
  }
}

const setColumns = function ({ tableOptions }) {
  let { columns } = cloneDeep(tableOptions)

  let slotNames = []
  let typeSlotNames = []
  let cellRenderNames = []

  let dictMaps = {}

  const DEFAULT_FIELD = 'default'

  columns.forEach((d, i) => {
    if (!d.field) {
      d.field = DEFAULT_FIELD + i
    }

    if (d.slots) {
      if (d.slots.header) {
        slotNames.push(d.slots.header)
      }
      if (d.slots.default) {
        slotNames.push(d.slots.default)
      }
    }

    if (d.type == 'radio' && !d.slots) {
      d.slots = {}
      d.slots.header = 'radio_header'
    }

    // 根据type设置默认插槽
    const { slotName: tSlots } = setTypeSlots(d)
    if (tSlots) {
      typeSlotNames.push(tSlots)
    }

    // 根据cellRender设置默认插槽
    const { slotName: cSlots } = setCellRenderSlots(d)

    if (cSlots) {
      cellRenderNames.push(cSlots)
    }

    // 字典
    if (d.dictCode) {
      dictMaps[d.field] = d.dictCode
      d.field += '_dictText'
    }
  })
  return { columns, dictMaps, slotNames, typeSlotNames, cellRenderNames }
}

/**
 * 处理表单配置以收集表单插槽名称
 *
 * 该函数的主要职责是遍历表单配置中的各项，以及其子项，以收集所有定义的默认插槽名称
 * 它通过递归方式处理配置中的每个项目，检查每个项目是否定义了默认插槽，并收集这些插槽名称
 *
 * @param {Object} formOptions - 表单配置对象，应包含 items 数组
 * @returns {Object} 返回一个对象，其中包含收集到的表单插槽名称数组
 */
const setFormSlot = function (formOptions) {
  // 初始化用于存储表单插槽名称的数组
  const formSlotNames = []

  /**
   * 辅助函数：递归处理 items 和 children 数组
   *
   * 该函数负责递归地检查传入的项目数组，寻找并收集默认插槽名称
   * 它通过检查每个项目是否包含 slots 属性以及该属性是否定义了默认插槽来收集插槽名称
   * 如果项目包含子项目（children），则递归调用自身以处理这些子项目
   *
   * @param {Array} items - 项目数组，可以是父项目数组或子项目数组
   */
  function processItems(items) {
    // 如果传入的不是数组，则直接返回，不进行处理
    if (!Array.isArray(items)) return

    // 遍历项目数组，处理每个项目
    for (const item of items) {
      // 如果项目定义了插槽且包含默认插槽，则将其添加到结果数组中
      if (item.slots && item.slots.default) {
        formSlotNames.push(item.slots.default)
      }

      // 如果项目包含子项目，则递归调用以处理这些子项目
      if (item.children && Array.isArray(item.children)) {
        processItems(item.children)
      }
    }
  }

  // 尝试处理表单配置，如果配置有效且包含 items 数组，则开始处理
  try {
    if (formOptions && Array.isArray(formOptions.items)) {
      processItems(formOptions.items)
    }
  } catch (error) {
    // 如果在处理过程中发生错误，则输出错误信息
    console.error('Error processing form options:', error)
  }

  // 返回包含收集到的表单插槽名称的对象
  return {
    formSlotNames
  }
}

export const initOptions = function (parentRef) {
  let { tableOptions } = parentRef

  // 处理 toolbarConfig 参数
  const toolbarConfig = settoolbarConfig(parentRef)

  // 处理 columns 参数
  // 处理 列插槽
  const { columns, dictMaps, slotNames, typeSlotNames, cellRenderNames } =
    setColumns(parentRef)

  const { formSlotNames } = setFormSlot(parentRef.formOptions)

  const radioConfig = {
    ...defaultOptions.radioConfig,
    ...tableOptions.radioConfig
  }

  const rowConfig = {
    ...defaultOptions.rowConfig,
    ...tableOptions.rowConfig
  }
  const checkboxConfig = {
    ...defaultOptions.checkboxConfig,
    ...tableOptions.checkboxConfig
  }

  return {
    columns,
    dictMaps,
    slotNames,
    typeSlotNames,
    cellRenderNames,
    toolbarConfig,
    radioConfig,
    checkboxConfig,
    rowConfig,
    formSlotNames
  }
}
